package cn.tedu.csmall.stock.webapi.controller;
 /*
 @Time: 2022/11/29 11:58
 @Author:GShuai
 @File:StockController.class
 @Software:IntelliJ IDEA
*/

import cn.tedu.csmall.commons.exception.CoolSharkServiceException;
import cn.tedu.csmall.commons.pojo.stock.dto.StockReduceCountDTO;
import cn.tedu.csmall.commons.restful.JsonResult;
import cn.tedu.csmall.commons.restful.ResponseCode;
import cn.tedu.csmall.stock.service.IStockService;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/base/stock")
@Api(tags = "库存管理")
public class StockController {
    @Autowired
    private IStockService stockService;

//    @PostMapping("/reduce/count")
    @GetMapping("/reduce/count")
    @ApiOperation("减少商品库存数")
    // SentinelResource 注解标记的控制器方法，会被Sentinel管理
    // 在这个方法第一次运行后，可以在Sentinel仪表台界面中设置限流规则
    // "减少库存的方法" 设置当前方法在仪表台中显示的名称
    // blockHandler 指定请求被限流时运行的方法名称
    // fallback 指定控制器方法运行发生异常时要执行的降级方法名称
    @SentinelResource(value = "减少库存的方法", blockHandler = "blockError", fallback = "fallbackError")
    public JsonResult reduceCommodityCount(StockReduceCountDTO stockReduceCountDTO){
        if(Math.random()<0.5){
            throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"抛出随机异常!");
        }
        // 调用业务逻辑层
        stockService.reduceCommodityCount(stockReduceCountDTO);
        return JsonResult.ok("商品库存减少完成！");
    }
    // Sentinel 自定义限流方法的定义
    //1. 访问修饰符必须时public
    //2. 返回值类型必须和限流的控制器方法一致
    //3. 方法名称必须是限流注解中blockHandler 中指定的名称
    //4. 参数列表必须限流的控制器方法一致，而且还要添加一个BlockException的参数
    public JsonResult blockError(StockReduceCountDTO stockReduceCountDTO, BlockException e){
        // 限流方法一般直接返回限流信息即可
        return JsonResult.failed(ResponseCode.BAD_REQUEST,"服务器忙请稍后再试！");
    }

    // 这个方法是Sentinel注解中拿fallback指定的降级方法
    // 将原定运行的控制器方法发送异常时，Sentinel会运行下面的方法
    // 降级方法中，可以编写一些对正常逻辑的补救措施，使用户受到损失最小
    public JsonResult fallbackError(StockReduceCountDTO stockReduceCountDTO){
        return JsonResult.failed(ResponseCode.BAD_REQUEST,"因为运行时发生异常,服务降级");
    }
}
